<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Three.js 相机与图层控制</title>
    <!-- 配置Three.js模块导入映射 -->
    <script type="importmap">
    {
        "imports": {
            "three": "https://threelab.cn/openthree/threejs/build/three.module.js",
            "three/addons/": "https://threelab.cn/openthree/threejs/examples/jsm/"
        }
    }
    </script>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            background-color: #1a1a1a;
            width: 100vw;
            height: 100vh;
            overflow: hidden;
        }
        
        #renderArea {
            width: 100%;
            height: 100%;
        }
        
        .info-panel {
            position: fixed;
            bottom: 15px;
            left: 15px;
            background-color: rgba(20, 20, 20, 0.8);
            color: #f0f0f0;
            padding: 8px 12px;
            border-radius: 4px;
            font-family: Arial, sans-serif;
            font-size: 12px;
            backdrop-filter: blur(3px);
        }
    </style>
</head>
<body>
    <!-- 3D渲染区域 -->
    <div id="renderArea"></div>
    
    <!-- 操作提示面板 -->
    <div class="info-panel">
        操作提示: 鼠标拖动旋转视角 | 滚轮缩放 | Shift+拖动平移
    </div>

    <script type="module">
        // 导入Three.js核心模块和所需组件
        import * as THREE from "three";
        import { OrbitControls } from "three/addons/controls/OrbitControls.js";
        import { GUI } from "three/addons/libs/lil-gui.module.min.js";

        /**
         * 初始化3D场景核心组件
         */
        class SceneManager {
            constructor(containerId) {
                // 获取渲染容器
                this.container = document.getElementById(containerId);
                
                // 初始化场景
                this.scene = new THREE.Scene();
                this.scene.background = new THREE.Color(0x1a1a1a);
                
                // 初始化相机
                this.initCamera();
                
                // 初始化渲染器
                this.initRenderer();
                
                // 初始化控制器
                this.initControls();
                
                // 初始化场景对象
                this.objects = {};
                
                // 创建场景内容
                this.createSceneContent();
                
                // 添加辅助工具
                this.addHelpers();
                
                // 创建GUI控制面板
                this.createControlsPanel();
                
                // 绑定窗口大小变化事件
                window.addEventListener('resize', () => this.handleResize());
                
                // 启动动画循环
                this.animate();
            }
            
            /**
             * 初始化相机
             */
            initCamera() {
                // 创建透视相机
                this.camera = new THREE.PerspectiveCamera(
                    50,  // 视野角度
                    this.container.clientWidth / this.container.clientHeight,  // 宽高比
                    0.1,  // 近平面
                    1000  // 远平面
                );
                
                // 设置相机初始位置
                this.camera.position.set(0, 1, 4);
                // 相机指向原点
                this.camera.lookAt(0, 0, 0);
            }
            
            /**
             * 初始化渲染器
             */
            initRenderer() {
                this.renderer = new THREE.WebGLRenderer({
                    antialias: true,          // 启用抗锯齿
                    alpha: false,             // 不使用透明背景
                    logarithmicDepthBuffer: true  // 启用对数深度缓冲区，解决远处物体渲染问题
                });
                
                // 设置渲染器尺寸
                this.renderer.setSize(
                    this.container.clientWidth,
                    this.container.clientHeight
                );
                
                // 将渲染器的DOM元素添加到容器中
                this.container.appendChild(this.renderer.domElement);
            }
            
            /**
             * 初始化控制器
             */
            initControls() {
                this.controls = new OrbitControls(
                    this.camera, 
                    this.renderer.domElement
                );
                
                // 配置控制器属性
                this.controls.enableDamping = true;      // 启用阻尼效果
                this.controls.dampingFactor = 0.1;       // 阻尼系数
                this.controls.enableZoom = true;         // 启用缩放
                this.controls.zoomSpeed = 0.7;           // 缩放速度
                this.controls.enablePan = true;          // 启用平移
                this.controls.panSpeed = 0.5;            // 平移速度
                this.controls.rotateSpeed = 0.5;         // 旋转速度
            }
            
            /**
             * 创建场景内容
             */
            createSceneContent() {
                // 创建平面（带纹理）
                this.createTexturedPlane();
                
                // 创建旋转立方体
                this.createRotatingCube();
            }
            
            /**
             * 创建带纹理的平面
             */
            createTexturedPlane() {
                // 创建平面几何体
                const planeGeometry = new THREE.PlaneGeometry(2, 2);
                
                // 加载纹理图片
                const textureLoader = new THREE.TextureLoader();
                // 使用示例图片替代本地图片
                const texture = textureLoader.load('https://picsum.photos/id/106/800/800');
                
                // 设置纹理参数
                texture.wrapS = THREE.RepeatWrapping;
                texture.wrapT = THREE.RepeatWrapping;
                texture.repeat.set(1, 1);
                texture.anisotropy = this.renderer.capabilities.getMaxAnisotropy();
                
                // 创建材质
                const planeMaterial = new THREE.MeshStandardMaterial({
                    map: texture,
                    side: THREE.DoubleSide  // 双面可见
                });
                
                // 创建平面网格并添加到场景
                this.objects.plane = new THREE.Mesh(planeGeometry, planeMaterial);
                this.scene.add(this.objects.plane);
            }
            
            /**
             * 创建旋转立方体（使用第二图层）
             */
            createRotatingCube() {
                // 创建立方体几何体
                const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);
                
                // 创建材质（使用金属质感材质替代基础材质）
                const cubeMaterial = new THREE.MeshStandardMaterial({
                    color: 0x4a90e2,
                    roughness: 0.3,
                    metalness: 0.8
                });
                
                // 创建立方体网格
                this.objects.cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
                
                // 设置立方体位置
                this.objects.cube.position.set(1, 0.5, 0);
                
                // 将立方体分配到第二图层（索引1）
                this.objects.cube.layers.set(1);
                
                // 添加到场景
                this.scene.add(this.objects.cube);
            }
            
            /**
             * 添加辅助工具
             */
            addHelpers() {
                // 添加坐标轴辅助线
                const axesHelper = new THREE.AxesHelper(5);
                this.scene.add(axesHelper);
                
                // 添加网格辅助线
                const gridHelper = new THREE.GridHelper(10, 10, 0x333333, 0x222222);
                this.scene.add(gridHelper);
                
                // 添加环境光，使物体可见
                const ambientLight = new THREE.AmbientLight(0xffffff, 0.8);
                this.scene.add(ambientLight);
                
                // 添加方向光，产生阴影效果
                const dirLight = new THREE.DirectionalLight(0xffffff, 1.2);
                dirLight.position.set(5, 10, 7.5);
                this.scene.add(dirLight);
            }
            
            /**
             * 创建GUI控制面板
             */
            createControlsPanel() {
                // 创建GUI实例
                this.gui = new GUI({ width: 300 });
                this.gui.title('相机与图层控制');
                
                // 相机属性控制组
                const cameraFolder = this.gui.addFolder('相机属性');
                cameraFolder.add(this.camera, 'fov', 10, 120, 1)
                    .name('视野角度')
                    .onChange(() => this.camera.updateProjectionMatrix());
                
                cameraFolder.add(this.camera, 'near', 0.001, 10, 0.001)
                    .name('近平面距离')
                    .onChange(() => this.camera.updateProjectionMatrix());
                
                cameraFolder.add(this.camera, 'far', 1, 2000, 1)
                    .name('远平面距离')
                    .onChange(() => this.camera.updateProjectionMatrix());
                
                cameraFolder.add(this.camera, 'zoom', 0.1, 5, 0.1)
                    .name('缩放系数')
                    .onChange(() => this.camera.updateProjectionMatrix());
                
                cameraFolder.open();
                
                // 相机位置控制组
                const positionFolder = this.gui.addFolder('相机位置');
                positionFolder.add(this.camera.position, 'x', -10, 10, 0.1).name('X轴位置');
                positionFolder.add(this.camera.position, 'y', -10, 10, 0.1).name('Y轴位置');
                positionFolder.add(this.camera.position, 'z', -10, 10, 0.1).name('Z轴位置');
                positionFolder.open();
                
                // 图层控制组
                const layerFolder = this.gui.addFolder('图层控制');
                layerFolder.add(this.camera.layers, 'mask')
                    .name('图层掩码')
                    .onChange(() => this.camera.updateProjectionMatrix())
                    .listen();
                
                layerFolder.add({ toggleLayer: () => this.camera.layers.toggle(1) }, 'toggleLayer')
                    .name('切换立方体图层可见性');
                
                // 重置按钮
                this.gui.add({ reset: () => this.resetScene() }, 'reset').name('重置场景');
            }
            
            /**
             * 重置场景
             */
            resetScene() {
                // 重置相机属性
                this.camera.fov = 50;
                this.camera.near = 0.1;
                this.camera.far = 1000;
                this.camera.zoom = 1;
                this.camera.position.set(0, 1, 4);
                this.camera.lookAt(0, 0, 0);
                this.camera.layers.mask = 1 | (1 << 1); // 显示所有图层
                this.camera.updateProjectionMatrix();
                
                // 重置GUI
                this.gui.reset();
            }
            
            /**
             * 处理窗口大小变化
             */
            handleResize() {
                // 更新相机宽高比
                this.camera.aspect = this.container.clientWidth / this.container.clientHeight;
                this.camera.updateProjectionMatrix();
                
                // 更新渲染器尺寸
                this.renderer.setSize(
                    this.container.clientWidth,
                    this.container.clientHeight
                );
            }
            
            /**
             * 动画循环
             */
            animate() {
                // 请求下一帧动画
                requestAnimationFrame(() => this.animate());
                
                // 旋转立方体
                if (this.objects.cube) {
                    this.objects.cube.rotation.y += 0.01;
                    this.objects.cube.rotation.x += 0.005;
                }
                
                // 更新控制器
                this.controls.update();
                
                // 渲染场景
                this.renderer.render(this.scene, this.camera);
            }
        }
        
        // 页面加载完成后初始化场景管理器
        window.addEventListener('load', () => {
            new SceneManager('renderArea');
        });
    </script>
</body>
</html>
    